/***************************************************************************************
 The copyright in this software is being made available under the BSD License, included
 below. This software may be subject to other third party rights,including patent rights,
 and no such rights are granted under this license.

 Regents of the Tsinghua University, Peking University, Zhejiang University, HKUST
 Tsinghua University, Peking University, Zhejiang University, HKUST 2011

 Copyright (c) 2011, Regents of the Tsinghua University, Peking University, Zhejiang
 University, HKUST. All Rights Reserved.

 Redistribution and use in source and binary forms, with or without modification, are
 permitted provided that the following conditions are met:
   * Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   * Neither the names of the copyright holders nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 OF SUCH DAMAGE.
***************************************************************************************/


#ifndef _GLOBAL_H_
#define _GLOBAL_H_

#include <stdio.h>
#include "defines.h"

typedef enum
{
    FRAME_CODING,
    FIELD_CODING,
    PAFF_CODING
} coding_type_t;

typedef enum
{
    FALSE,
    TRUE
} boolean_t;

typedef unsigned char byte;

byte ** p_img_y_dec;
byte ** p_img_uv_dec[2];

byte **imgY_prev;
byte ***imgUV_prev;

byte **imgY_ref;
byte ***imgUV_ref;

int Bframe_ctr;
byte prevP_tr, nextP_tr, P_interval;
int frame_no;


int *parity_fld;


byte nextP_tr_frm;

#define ET_SIZE 300
char errortext[ET_SIZE];

int CSyntax;
int StartCodeValue;

int Min_V_MV;
int Max_V_MV;
int Min_H_MV;
int Max_H_MV;

typedef enum
{
    SE_HEADER,
    SE_MBTYPE,
    SE_REFFRAME,
    SE_MVD,
    SE_INTRAPREDMODE,
    SE_CBP_INTRA,
    SE_LUM_DC_INTRA,
    SE_CHR_DC_INTRA,
    SE_LUM_AC_INTRA,
    SE_CHR_AC_INTRA,
    SE_CBP_INTER,
    SE_LUM_DC_INTER,
    SE_CHR_DC_INTER,
    SE_LUM_AC_INTER,
    SE_CHR_AC_INTER,
    SE_DELTA_QUANT_INTER,
    SE_DELTA_QUANT_INTRA,
    SE_MAX_ELEMENTS
} se_type_t;

typedef enum
{
    BITS_TOTAL_MB,
    BITS_HEADER_MB,
    BITS_INTER_MB,
    BITS_CBP_MB,
    BITS_COEFF_Y_MB,
    BITS_COEFF_UV_MB,
    MAX_BITCOUNTER_MB
} bit_count_type_t;

typedef enum
{
    P_IMG = 0,
    B_IMG,
    I_IMG,
    MAX_IMG_TYPE
} img_type_t;

typedef enum
{
    FW,
    BW,
    BI,
    INTRA,
} direction_t;

typedef enum
{
    SKIP,
    INTER16x16,
    //INTER16x8,
    //INTER8x16,
    INTER8x8,
    INTER4x4,
    I8MB,
    I4MB,
    MAX_MODE_NUM
} mode_type;

typedef enum
{
    SUBBLOCK_INTRA8x8,
    SUBBLOCK_INTER8x8,
    SUBBLOCK_INTRA4x4,
    SUBBLOCK_INTER4x4
} sub_mode_t;

typedef struct mv_par
{
    short x;
    short y;
    short ref;
} mv_t;

typedef struct bi_mv_par
{
    mv_t fw_mv;
    mv_t bw_mv;
} bi_mv_t;

typedef struct bbv_buffer
{

    char  bbv_mode;
    char  vec_flag;
    int   bbs_size;
    int   bitrate;
    int   curr_frm_max_bit;
    int   curr_frm_min_bit;
    int   frm_no;
    int   check_continue;
    int   *frame_bits;
    float frame_rate;
    float bbv_delay;
    float low_delay;
    float frm_out_interval;

    int   frame_code_bits;


} bbv_buffer_t;

typedef struct syntaxelement
{
    int type;
    int value1;
    int value2;
    int len;
    int inf;
    int context;
    int k;
    int golomb_grad;
    int golomb_maxlevels;
    unsigned int bitpattern;
#if TRACE
#define       TRACESTRING_SIZE 100
    char tracestring[TRACESTRING_SIZE];
#endif
    void ( *mapping ) ( int len, int info, int *value1, int *value2 );
} syntax_element_t;

typedef struct macroblock
{
    int qp;
    int slice_nr;
    int delta_quant;
    int mb_type;
    int subblock_type[4];
    int blocksize;
    int subblocksize[4];
    int cbp, cbp_blk, cbp01;
    //int b8mode[4];
    int b8pdir[4];
    unsigned long cbp_bits;
    struct macroblock *mb_available[3][3];
    int mvd[2][2][2][2];


    int b8mode[2][2]; //save b8dir for B_IMG INTER8x8,
    int b16mode;
    int b4mode[2][2][2][2];
    int b8_ref[2][2];
    int b4_ref[4][4]; //[B8][B4]
    mv_t mvd_4x4[4][4];
    bi_mv_t bi_mvd_4x4[4][4];

    int uvmode;      //u and v use the same mode now
    int y_dc[2][2]; //save the dc level of every b8 block
    int y_16x16_dc;
    int y_4x4_dc[2][2][2][2];
    int uv_dc[2];   // save the dc level of every uv block

    int transform_16x16;
    int transform_4x4[4];
    int cbp_16x16;
    int cbp_4x4[4];

    int qp_16x16;
    int qp_4x4;

} macroblock_t;

typedef struct bitstream
{
    int read_len;
    int code_len;
    int frame_bitoffset;
    int bitstream_length;
    byte *stream_buffer;
} bitstream_t;

typedef struct image_par
{
    int number;
    int current_mb_nr;
    int max_mb_nr;
    int current_slice_nr;
    int tr;
    int qp;
#ifdef OPT_HP
	int tag_hp;
#endif
    int type;
    int width;
    int height;
    int width_cr;
    int height_cr;
    int mb_y;
    int mb_x;
    int block_y;
    int pix_y;
    int pix_x;
    int pix_c_y;
    int block_x;
    int pix_c_x;

    int mpr[16][16];
    int m7[16][16];
    int m8[ /*2 */ 4][8][8];
    int cof[4][ /*6 */ 8][4][4];
    int cofu[4];
    int quad[256];
    int cod_counter;

    int imgtr_next_P;
    int imgtr_last_P;
    int tr_frm;
    int tr_fld;
    int imgtr_last_prev_P;

    int no_forward_reference;
    int seq_header_indicate;
    int B_discard_flag;

    int is_discard_frame; //to search I frame, if the first frame is not I frame, then discard it.
    int next_frame_type; //to get the next frame's type. e.x;The current frame is I, then the next is P frame.There are no I-pictures.
    int succe_b; //the number of B frames inserted between two neighboring I(or P) and P frames.
    int b_num; //the number of existing B frame(s) to be coded. It depends on succe_b and the current code(decoded) frame.

    int subblock_x;
    int subblock_y;

    int buf_cycle;


    int toppoc;
    int bottompoc;
    int framepoc;
    unsigned int frame_num;

    unsigned int pic_distance;
    int delta_pic_order_cnt_bottom;

    signed int PicDistanceMsb;
    unsigned int PrevPicDistanceLsb;
    signed int CurrPicDistanceMsb;
    unsigned int ThisPOC;

    int PicWidthInMbs;
    int PicHeightInMbs;
    int PicSizeInMbs;

    int block8_x, block8_y;
    int structure;
    int pn;
    int buf_used;
    int buf_size;
    //int picture_structure;
    int advanced_pred_mode_disable;
    int types;
    int current_mb_nr_fld;

    int slice_weighting_flag;
    int lum_scale[4];
    int lum_shift[4];
    int chroma_scale[4];
    int chroma_shift[4];
    int mb_weighting_flag;
    int weighting_prediction;
    int mpr_weight[16][16];
    int top_bot;
    int Bframe_number;
    int auto_crop_right;
    int auto_crop_bottom;

    int new_seq_header_flag;
    int new_sequence_flag;
    int last_pic_bbv_delay;
    int ref_num;
    int vbs_qp_16x16;
    int vbs_qp_4x4;
} image_t;


macroblock_t *mb_data;

extern image_t *img;
extern bitstream_t *currStream;


typedef struct snr_par
{
    float snr_y;
    float snr_u;
    float snr_v;
    float snr_y1;
    float snr_u1;
    float snr_v1;
    float snr_ya;
    float snr_ua;
    float snr_va;
} snr_t;

int tot_time;

typedef struct inp_par
{
    char infile[1000];
    char outfile[1000];
    char reffile[1000];
    int FileFormat;
    int buf_cycle;
    int LFParametersFlag;
    int yuv_structure;
    int check_BBV_flag;
} input_t;


typedef struct input_bitstream
{
    FILE *f;
    unsigned char buf[SVA_STREAM_BUF_SIZE];
    unsigned int uClearBits;
    unsigned int uPre3Bytes;
    int iBytePosition;
    int iBufBytesNum;
    int iClearBitsNum;
    int iStuffBitsNum;
    int iBitsCount;
} input_bitstream_t;

typedef struct prob_state
{
    int lps_interval;
    int next_state_lps;
    int next_state_mps;
    int do_switch_mps;
} prob_state_t;

typedef struct prob_context
{
    int mps;
    int state;
    prob_state_t* prob_fsm;
} prob_context_t;

#define NUM_EQ_CX_QCODER           1

#define NUM_CBP_CX_QCODER_INTRA    5
#define NUM_CBP_CX_QCODER_INTER    5

#define NUM_DELTAQP_CX_QCODER      4
#define NUM_INTRAMODE_CX_QCODER    2
#define NUM_INTERREF_CX_QCODER     1

#define NUM_INTERSKIP_CX_QCODER    1
#define NUM_MBTYPE_CX_QCODER       3
#define NUM_MBSUBTYPE_CX_QCODER    2
#define NUM_BLOCKSIZE_CX_QCODER    1
#define NUM_SUBBLOCKSIZE_CX_QCODER 1
#define NUM_PRED_DIRECTION_CX_QCODER 2

#define NUM_MVD_CX_QCODER_MAX      5
#define NUM_MVD_CX_16x16_QCODER    5
#define NUM_MVD_CX_8x8_QCODER      5
#define NUM_MVD_CX_4x4_QCODER      5

#define NUM_EOBFLAG_CX_QCODER      1


//4x4 block
#define NUM_COEFF_B4_CX_QCODER_R_MAX   9
#define NUM_COEFF_B4_CX_QCODER_C_MAX   6
#define NUM_COEFF_B4_CX_QCODER_R_INTRA   9
#define NUM_COEFF_B4_CX_QCODER_C_INTRA   6
#define NUM_COEFF_B4_CX_QCODER_R_INTER   9
#define NUM_COEFF_B4_CX_QCODER_C_INTER   6

//8x8 block
#define NUM_COEFF_B8_CX_QCODER_R_MAX   33
#define NUM_COEFF_B8_CX_QCODER_C_MAX   6
//8x8 block for luma
#define NUM_COEFF_B8_CX_QCODER_R_INTRA   33
#define NUM_COEFF_B8_CX_QCODER_C_INTRA   6
#define NUM_COEFF_B8_CX_QCODER_R_INTER   33
#define NUM_COEFF_B8_CX_QCODER_C_INTER   6
//8x8 block for chroma
#define NUM_COEFF_B8_CX_QCODER_R_INTRA_CHROMA   33
#define NUM_COEFF_B8_CX_QCODER_C_INTRA_CHROMA   6
#define NUM_COEFF_B8_CX_QCODER_R_INTER_CHROMA   33
#define NUM_COEFF_B8_CX_QCODER_C_INTER_CHROMA   6

//16x16 block
#define NUM_COEFF_B16_CX_QCODER_R_MAX  33
#define NUM_COEFF_B16_CX_QCODER_C_MAX  6
#define NUM_COEFF_B16_CX_QCODER_R_INTRA  33
#define NUM_COEFF_B16_CX_QCODER_C_INTRA  6
#define NUM_COEFF_B16_CX_QCODER_R_INTER  33
#define NUM_COEFF_B16_CX_QCODER_C_INTER  6


typedef struct qcoder_env
{
    unsigned long interval;
    unsigned long code;
    int code_bits;
    int bin;
    int state;
    int b;
    int isEof;

    prob_context_t eq_prob_context;

    prob_context_t cx_eob_flag;

    prob_context_t cx_intra_cbp[NUM_CBP_CX_QCODER_INTRA];
    prob_context_t cx_inter_cbp[NUM_CBP_CX_QCODER_INTER];

    prob_context_t cx_intra_luma_mode[NUM_INTRAMODE_CX_QCODER];
    prob_context_t cx_intra_chroma_mode[NUM_INTRAMODE_CX_QCODER];

    prob_context_t cx_inter_ref;

#define NUM_PARTITION 3 //16x16, 8x8, 4x4
#define NUM_DIRECTION 3 //fw bw bi not intra
    prob_context_t cx_inter_skip[NUM_INTERSKIP_CX_QCODER];
    prob_context_t cx_mbsubtype_Direction[NUM_PARTITION][NUM_DIRECTION];
    prob_context_t cx_blocksize[NUM_BLOCKSIZE_CX_QCODER];
    prob_context_t cx_subblocksize[NUM_SUBBLOCKSIZE_CX_QCODER];
    prob_context_t cx_pred_direction[NUM_PRED_DIRECTION_CX_QCODER];
    prob_context_t cx_mbsubtype[NUM_MBSUBTYPE_CX_QCODER];
    prob_context_t cx_mbtype[NUM_MBTYPE_CX_QCODER];
    prob_context_t cx_mvd_x[NUM_MVD_CX_QCODER_MAX];
    prob_context_t cx_mvd_y[NUM_MVD_CX_QCODER_MAX];
    prob_context_t cx_delta_qp[NUM_DELTAQP_CX_QCODER];

    prob_context_t cx_transform_s4_flag;
    prob_context_t cx_transform_s16_flag;

    prob_context_t cx_luma_8x8[NUM_COEFF_B8_CX_QCODER_R_MAX][NUM_COEFF_B8_CX_QCODER_C_MAX];
    prob_context_t cx_luma_4x4[NUM_COEFF_B4_CX_QCODER_R_MAX][NUM_COEFF_B4_CX_QCODER_C_MAX];
    prob_context_t cx_luma_16x16[NUM_COEFF_B16_CX_QCODER_R_MAX][NUM_COEFF_B16_CX_QCODER_C_MAX];
    prob_context_t cx_chroma_8x8[NUM_COEFF_B8_CX_QCODER_R_MAX][NUM_COEFF_B8_CX_QCODER_C_MAX];

    prob_context_t cx_eob_flag_8x8[64];
    prob_context_t cx_eob_flag_4x4[16];
    prob_context_t cx_eob_flag_chroma[64];
} qcoder_env_t;

qcoder_env_t* qcoder;
extern input_t *input;

#if defined(WIN32) && !defined(__MINGW32__)
int p_out;
int p_ref;
#else
FILE *p_out;
FILE *p_ref;
#endif

FILE *p_log;

#if TRACE
FILE *p_trace;
#endif

FILE *p_sreport;

void set_MB_parameters( image_t *img, input_t *inp, int mb );

void init_conf( input_t *inp, int numpar, char **config_str );
void report( input_t *inp, image_t *img, snr_t *snr );

#if REC_YUV
#if defined(WIN32) && !defined(__MINGW32__)
void find_snr( snr_t *snr, image_t *img, int p_ref );
#else
void find_snr( snr_t *snr, image_t *img, FILE * p_ref );
#endif
#endif

void init( image_t *img );

int decode_one_frame( image_t *img, input_t *inp, snr_t *snr );
void init_frame( image_t *img, input_t *inp );

#if defined(WIN32) && !defined(__MINGW32__)
void write_frame( image_t *img, int p_out );
void write_prev_Pframe( image_t *img, int p_out );
#else
void write_frame( image_t *img, FILE * p_out );
void write_prev_Pframe( image_t *img, FILE * p_out );
#endif

int read_new_slice();
void decode_one_slice( image_t *img, input_t *inp );
void picture_data( image_t *img, input_t *inp );
void start_macroblock( image_t *img, input_t *inp );
void read_one_macroblock( image_t *img, input_t *inp );

int read_one_macroblock_Bframe( image_t *img, input_t *inp );
int decode_one_macroblock( image_t *img, input_t *inp );
int decode_one_macroblock_Bframe( image_t *img );
int exit_macroblock( image_t *img, input_t *inp, int eos_bit );


int Header();
void get_block_uv( macroblock_t *currMB, int uv );
void get_block_4x4( int ref_frame, int x_pos, int y_pos, image_t *img, int block[4][4] );

void get_block( int ref_frame, int x_pos, int y_pos, image_t *img, int block[8][8] );
void CheckAvailabilityOfNeighbors( image_t *img );

void error( char *text, int code );

int get_mem4D_mv( mv_t *****array4D, int idx, int frames, int rows, int columns );
int get_mem4D_bi_mv( bi_mv_t *****array4D, int idx, int frames, int rows, int columns );
void free_mem4D_mv( mv_t ****array4D, int idx, int frames );
void free_mem4D_bi_mv( bi_mv_t ****array4D, int idx, int frames );

int init_global_buffers( input_t *inp, image_t *img );
void free_global_buffers( input_t *inp, image_t *img );

void update_picture_buffers();
#ifdef OPT_HP
void update_picture_buffers2();
#endif
void frame_postprocessing( image_t *img );

void report_frame( snr_t *snr, int tmp_time );

#define PAYLOAD_TYPE_IDERP 8

bitstream_t *alloc_bitstream();
qcoder_env_t* alloc_qcoder();
void free_bitstream();
void tracebits2( const char *trace_str, int len, int info );

int get_direct_mv( int ******mv, int mb_x, int mb_y );
void free_direct_mv( int *****mv, int mb_x, int mb_y );

int *****direct_mv;
int ipdirect_x, ipdirect_y;
int demulate_enable;

int aspect_ratio_information;
int frame_rate_code;
int bit_rate_value;
int bbv_buffer_size;

int slice_row_nr;
int currentbitoffset;
int currentBytePosition;
int chroma_format;
int profile_id;
int level_id;
int num_b_picture;
//int progressive_sequence;
int horizontal_size;
int vertical_size;
int chroma_format;
int sample_precision;
int aspect_ratio_information;
int pictureApplicationDataEnable;
int frame_rate_code;
int bit_rate;
int bit_rate_lower;
int bit_rate_upper;

int video_format;
int video_range;
int color_description;
int color_primaries;
int transfer_characteristics;
int matrix_coefficients;
int display_horizontal_size;
int display_vertical_size;


int FrameNum;
int eos;
int pre_img_type;
int pre_img_types;

int pre_img_tr;
int pre_img_qp;
int pre_tmp_time;
int RefPicExist;
snr_t *snr;

int vec_flag;

int reserved_data;
int copyright_flag;
int copyright_identifier;
int original_or_copy;
int copyright_number_1;
int copyright_number_2;
int copyright_number_3;

int stream_length_flag;
int stream_length;
int picture_distance;
int picture_decode_order_flag;
int picture_decode_order;
int top_field_first;
int frame_pred_frame_dct;
int repeat_first_field;
int progressive_frame;

int fixed_picture_qp;
int picture_qp;
int low_delay;
int time_code_flag;
int time_code;
//int skip_mode_flag;
int vbs_enable;
//int vbs_qp_16x16;
//int vbs_qp_4x4;
int loop_filter_disable;
int loop_filter_parameter_flag;
int alpha_offset;
int beta_offset;
int bby_delay;
int hour;
int minute;
int sec;
int frame_offset;
int bbv_check_times;


int luma_scale;
int luma_shift;
int chroma_scale;
int chroma_shift;
int second_IField;

int picture_coding_type;
int bbv_delay;
int picture_reference_flag;
int dct_adaptive_flag;
float singlefactor;
int marker_bit;

int frame_centre_horizontal_offset[4];
int frame_centre_vertical_offset[4];

int start_code_prefix;
int img_width;
int slice_vertical_position;
int slice_vertical_position_extension;
int slice_start_code;
int fixed_picture_qp;
int fixed_slice_qp;
int slice_qp;
int StartCodePosition;

#define PICTURE_START_CODE    0xB3
//#define PB_PICTURE_START_CODE   0xB6
#define SLICE_START_CODE_MIN    0x00
#define SLICE_START_CODE_MAX    0xAF
#define USER_DATA_START_CODE    0xB2
#define SEQUENCE_HEADER_CODE    0xB0
#define EXTENSION_START_CODE    0xB5
#define SEQUENCE_END_CODE       0xB1
#define VIDEO_EDIT_CODE         0xB7

#define SEQUENCE_DISPLAY_EXTENSION_ID            2
#define COPYRIGHT_EXTENSION_ID                   4
#define CAMERAPARAMETERS_EXTENSION_ID            11
#define PICTURE_DISPLAY_EXTENSION_ID             7

byte ** img_y_dec[MAXREFNUM_PLUS_1];
byte ** img_uv_dec[2][MAXREFNUM_PLUS_1];


typedef struct camera_para
{
    int reserved;
    int camera_id;
    int height_of_image_device;
    int focal_length;
    int f_number;
    int vertical_angle_of_view;
    int camera_position_x;
    int camera_position_y;
    int camera_position_z;
    int camera_direction_x;
    int camera_direction_y;
    int camera_direction_z;
    int image_plane_vertical_x;
    int image_plane_vertical_y;
    int image_plane_vertical_z;
} camera_para_t;

extern camera_para_t *camera;

unsigned long int bn;



typedef struct frame
{
    int used;
    int valid;
    //<! 1: normal reference frame, 0: frame inserted to the buffer
    int picID;
    int lt_picID;
    byte **mref;
    byte ***mcef;
    int islong;

    unsigned int layerNumber;
    unsigned int subSequenceIdentifier;
    int parity;
} frame_t;

typedef struct frame_buffer
{
    frame_t **picbuf_short;
    frame_t **picbuf_long;
    int short_size;
    int long_size;
    int short_used;
    int long_used;
} frame_buffer_t;


byte **mref_fref_frm[2];
byte **mref_bref_frm[2];
byte **mcef_fref_frm[2][2];
byte **mcef_bref_frm[2][2];

byte **mref_fref_fld[2];
byte **mref_bref_fld[2];
byte **mcef_fref_fld[2][2];
byte **mcef_bref_fld[2][2];

byte **mref_fref[2];
byte **mref_bref[2];
byte **mcef_fref[2][2];
byte **mcef_bref[2][2];


mv_t    **frm_mv[MAX_REF_NUM_PLUS_1];
bi_mv_t **frm_bi_mv; //only used for B frame
mv_t    ****frm_mv_4x4[MAX_REF_NUM_PLUS_1];
bi_mv_t ****frm_bi_mv_4x4; //only used for B frame
int qcoder_decode_intra_cbp( qcoder_env_t* qcoder );
int qcoder_decode_inter_cbp( qcoder_env_t* qcoder );
int qcoder_decode_delta_qp( qcoder_env_t* qcoder );
int qcoder_decode_intra_luma_mode( qcoder_env_t* qcoder );
int qcoder_decode_intra_chroma_mode( qcoder_env_t* qcoder );
void open_input_bitstream( char *fn );
int is_end_of_bitstream();
void close_input_bitstream();
int get_one_unit( char *buf, int *startcodepos, int *length );
void qcoder_init( qcoder_env_t* qcoder, bitstream_t* currStream );
int check_start_code();
void qcoder_flush( qcoder_env_t* qcoder );
int qcoder_decode_eobflag( qcoder_env_t* qcoder );
int qcoder_decode_luma_b8x8_coeff( qcoder_env_t* qcoder, int idx, int intra );
int qcoder_decode_chroma_b8x8_coeff( qcoder_env_t* qcoder, int idx, int intra );
int qcoder_decode_luma_b4x4_coeff( qcoder_env_t* qcoder, int idx, int intra );
int qcoder_decode_luma_b16x16_coeff( qcoder_env_t* qcoder, int idx, int intra );
int qcoder_decode_transform_s4_flag( qcoder_env_t* qcoder );
int qcoder_decode_transform_s16_flag( qcoder_env_t* qcoder );
int get_uv( int LenInBits, char *tracestring );

//added by ckj inter4x4 will not be deblocked currently
#if DEBLOCK

byte  **p_img_y_dec_deblock;
byte ***p_img_uv_dec_deblock;
byte  **imgY_prev_deblock;
byte ***imgUV_prev_deblock;

void CopyAndDeblockFrame( image_t *img, byte **bufY, byte ***bufUV, byte **imgY, byte ***imgUV );

#endif

#endif
